home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / LANG / ADA / GNAT / !gcc / adainc / 2 / adb / a-strbou < prev    next >
Text File  |  1996-02-12  |  55KB  |  1,746 lines

  1. ------------------------------------------------------------------------------
  2. --                                                                          --
  3. --                         GNAT RUNTIME COMPONENTS                          --
  4. --                                                                          --
  5. --                  A D A . S T R I N G S . B O U N D E D                   --
  6. --                                                                          --
  7. --                                 B o d y                                  --
  8. --                                                                          --
  9. --                            $Revision: 1.14 $                             --
  10. --                                                                          --
  11. --        Copyright (C) 1992,1993,1994 Free Software Foundation, Inc.       --
  12. --                                                                          --
  13. -- GNAT is free software;  you can  redistribute it  and/or modify it under --
  14. -- terms of the  GNU General Public License as published  by the Free Soft- --
  15. -- ware  Foundation;  either version 2,  or (at your option) any later ver- --
  16. -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
  17. -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
  18. -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
  19. -- for  more details.  You should have  received  a copy of the GNU General --
  20. -- Public License  distributed with GNAT;  see file COPYING.  If not, write --
  21. -- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
  22. -- MA 02111-1307, USA.                                                      --
  23. --                                                                          --
  24. -- As a special exception,  if other files  instantiate  generics from this --
  25. -- unit, or you link  this unit with other files  to produce an executable, --
  26. -- this  unit  does not  by itself cause  the resulting  executable  to  be --
  27. -- covered  by the  GNU  General  Public  License.  This exception does not --
  28. -- however invalidate  any other reasons why  the executable file  might be --
  29. -- covered by the  GNU Public License.                                      --
  30. --                                                                          --
  31. -- GNAT was originally developed  by the GNAT team at  New York University. --
  32. -- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
  33. --                                                                          --
  34. ------------------------------------------------------------------------------
  35.  
  36. with Ada.Strings.Maps;   use Ada.Strings.Maps;
  37. with Ada.Strings.Search;
  38.  
  39. package body Ada.Strings.Bounded is
  40.  
  41.    package body Generic_Bounded_Length is
  42.  
  43.       ---------
  44.       -- "=" --
  45.       ---------
  46.  
  47.       function "=" (Left, Right : in Bounded_String) return Boolean is
  48.       begin
  49.          return Left.Length = Right.Length
  50.            and then Left.Data (1 .. Left.Length) =
  51.                     Right.Data (1 .. Right.Length);
  52.       end "=";
  53.  
  54.       function "="  (Left : in Bounded_String; Right : in String)
  55.          return Boolean is
  56.       begin
  57.          return Left.Length = Right'Length
  58.            and then Left.Data (1 .. Left.Length) = Right;
  59.       end "=";
  60.  
  61.       function "="  (Left : in String; Right : in Bounded_String)
  62.          return Boolean is
  63.       begin
  64.          return Left'Length = Right.Length
  65.            and then Left = Right.Data (1 .. Right.Length);
  66.       end "=";
  67.  
  68.       ---------
  69.       -- "<" --
  70.       ---------
  71.  
  72.       function "<" (Left, Right : in Bounded_String) return Boolean is
  73.       begin
  74.          return Left.Data (1 .. Left.Length) < Right.Data (1 .. Right.Length);
  75.       end "<";
  76.  
  77.       function "<"  (Left : in Bounded_String; Right : in String)
  78.          return Boolean is
  79.       begin
  80.          return Left.Data (1 .. Left.Length) < Right;
  81.       end "<";
  82.  
  83.       function "<"  (Left : in String; Right : in Bounded_String)
  84.          return Boolean is
  85.       begin
  86.          return Left < Right.Data (1 .. Right.Length);
  87.       end "<";
  88.  
  89.       ----------
  90.       -- "<=" --
  91.       ----------
  92.  
  93.       function "<=" (Left, Right : in Bounded_String) return Boolean is
  94.       begin
  95.          return Left.Data (1 .. Left.Length) <= Right.Data (1 .. Right.Length);
  96.       end "<=";
  97.  
  98.       function "<="  (Left : in Bounded_String; Right : in String)
  99.          return Boolean is
  100.       begin
  101.          return Left.Data (1 .. Left.Length) <= Right;
  102.       end "<=";
  103.  
  104.       function "<="  (Left : in String; Right : in Bounded_String)
  105.          return Boolean is
  106.       begin
  107.          return Left <= Right.Data (1 .. Right.Length);
  108.       end "<=";
  109.  
  110.       ---------
  111.       -- ">" --
  112.       ---------
  113.  
  114.       function ">" (Left, Right : in Bounded_String) return Boolean is
  115.       begin
  116.          return Left.Data (1 .. Left.Length) > Right.Data (1 .. Right.Length);
  117.       end ">";
  118.  
  119.       function ">"  (Left : in Bounded_String; Right : in String)
  120.          return Boolean is
  121.       begin
  122.          return Left.Data (1 .. Left.Length) > Right;
  123.       end ">";
  124.  
  125.       function ">"  (Left : in String; Right : in Bounded_String)
  126.          return Boolean is
  127.       begin
  128.          return Left > Right.Data (1 .. Right.Length);
  129.       end ">";
  130.  
  131.       ----------
  132.       -- ">=" --
  133.       ----------
  134.  
  135.       function ">=" (Left, Right : in Bounded_String) return Boolean is
  136.       begin
  137.          return Left.Data (1 .. Left.Length) >= Right.Data (1 .. Right.Length);
  138.       end ">=";
  139.  
  140.       function ">="  (Left : in Bounded_String; Right : in String)
  141.          return Boolean is
  142.       begin
  143.          return Left.Data (1 .. Left.Length) >= Right;
  144.       end ">=";
  145.  
  146.       function ">="  (Left : in String; Right : in Bounded_String)
  147.          return Boolean is
  148.       begin
  149.          return Left >= Right.Data (1 .. Right.Length);
  150.       end ">=";
  151.  
  152.       ---------
  153.       -- "*" --
  154.       ---------
  155.  
  156.       function "*"
  157.         (Left  : in Natural;
  158.          Right : in Character)
  159.          return  Bounded_String
  160.       is
  161.          Result : Bounded_String;
  162.  
  163.       begin
  164.          if Left > Max_Length then
  165.             raise Ada.Strings.Length_Error;
  166.          else
  167.             Result.Length := Left;
  168.  
  169.             for J in 1 .. Left loop
  170.                Result.Data (J) := Right;
  171.             end loop;
  172.          end if;
  173.  
  174.          return Result;
  175.       end "*";
  176.  
  177.       function "*"
  178.         (Left  : in Natural;
  179.          Right : in String)
  180.          return  Bounded_String
  181.       is
  182.          Result : Bounded_String;
  183.          Pos    : Positive         := 1;
  184.          Rlen   : constant Natural := Right'Length;
  185.          Nlen   : constant Natural := Left * Rlen;
  186.  
  187.       begin
  188.          if Nlen > Max_Length then
  189.             raise Ada.Strings.Index_Error;
  190.          else
  191.             Result.Length := Nlen;
  192.  
  193.             if Nlen > 0 then
  194.                for J in 1 .. Left loop
  195.                   Result.Data (Pos .. Pos + Rlen - 1) := Right;
  196.                   Pos := Pos + Rlen;
  197.                end loop;
  198.             end if;
  199.          end if;
  200.  
  201.          return Result;
  202.       end "*";
  203.  
  204.       function "*"
  205.         (Left  : in Natural;
  206.          Right : in Bounded_String)
  207.          return  Bounded_String
  208.       is
  209.          Result : Bounded_String;
  210.          Pos    : Positive := 1;
  211.          Rlen   : constant Length_Range := Right.Length;
  212.          Nlen   : constant Natural      := Left * Rlen;
  213.  
  214.       begin
  215.          if Nlen > Max_Length then
  216.             raise Ada.Strings.Length_Error;
  217.  
  218.          else
  219.             Result.Length := Nlen;
  220.  
  221.             if Nlen > 0 then
  222.                for J in 1 .. Left loop
  223.                   Result.Data (Pos .. Pos + Rlen - 1) :=
  224.                     Right.Data (1 .. Rlen);
  225.                   Pos := Pos + Rlen;
  226.                end loop;
  227.             end if;
  228.          end if;
  229.  
  230.          return Result;
  231.       end "*";
  232.  
  233.       ---------
  234.       -- "&" --
  235.       ---------
  236.  
  237.       function "&" (Left, Right : in Bounded_String)
  238.          return Bounded_String is
  239.          Result : Bounded_String;
  240.          Llen   : constant Length_Range := Left.Length;
  241.          Rlen   : constant Length_Range := Right.Length;
  242.          Nlen   : constant Natural      := Llen + Rlen;
  243.  
  244.       begin
  245.          if Nlen > Max_Length then
  246.             raise Ada.Strings.Length_Error;
  247.          else
  248.             Result.Length := Nlen;
  249.             Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
  250.             Result.Data (Llen + 1 .. Nlen) := Right.Data (1 .. Rlen);
  251.          end if;
  252.  
  253.          return Result;
  254.       end "&";
  255.  
  256.       function "&" (Left : in Bounded_String; Right : in String)
  257.          return Bounded_String is
  258.          Result : Bounded_String;
  259.          Llen   : constant Length_Range := Left.Length;
  260.  
  261.          Nlen   : constant Natural      := Llen + Right'Length;
  262.  
  263.       begin
  264.          if Nlen > Max_Length then
  265.             raise Ada.Strings.Length_Error;
  266.          else
  267.             Result.Length := Nlen;
  268.             Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
  269.             Result.Data (Llen + 1 .. Nlen) := Right;
  270.          end if;
  271.          return Result;
  272.       end "&";
  273.  
  274.       function "&" (Left : in String; Right : in Bounded_String)
  275.          return Bounded_String is
  276.          Result : Bounded_String;
  277.          Llen   : constant Length_Range := Left'Length;
  278.          Rlen   : constant Length_Range := Right.Length;
  279.          Nlen   : constant Natural      := Llen + Rlen;
  280.  
  281.       begin
  282.          if Nlen > Max_Length then
  283.             raise Ada.Strings.Length_Error;
  284.          else
  285.             Result.Length := Nlen;
  286.             Result.Data (1 .. Llen) := Left;
  287.             Result.Data (Llen + 1 .. Nlen) := Right.Data (1 .. Rlen);
  288.          end if;
  289.  
  290.          return Result;
  291.       end "&";
  292.  
  293.       function "&"
  294.         (Left  : in Bounded_String;
  295.          Right : in Character)
  296.          return  Bounded_String
  297.       is
  298.          Result : Bounded_String;
  299.          Llen   : constant Length_Range := Left.Length;
  300.  
  301.       begin
  302.          if Llen = Max_Length then
  303.             raise Ada.Strings.Length_Error;
  304.          else
  305.             Result.Length := Llen + 1;
  306.             Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
  307.             Result.Data (Result.Length) := Right;
  308.          end if;
  309.  
  310.          return Result;
  311.       end "&";
  312.  
  313.       function "&" (Left : in Character; Right : in Bounded_String)
  314.          return Bounded_String is
  315.          Result : Bounded_String;
  316.          Rlen   : Length_Range := Right.Length;
  317.  
  318.       begin
  319.          if Rlen = Max_Length then
  320.             raise Ada.Strings.Length_Error;
  321.          else
  322.             Result.Length := Rlen + 1;
  323.             Result.Data (1) := Left;
  324.             Result.Data (2 .. Result.Length) := Right.Data (1 .. Rlen);
  325.          end if;
  326.  
  327.          return Result;
  328.       end "&";
  329.  
  330.       ------------
  331.       -- Append --
  332.       ------------
  333.  
  334.       --  Case of Bounded_String and Bounded_String
  335.  
  336.       function Append
  337.         (Left, Right : in Bounded_String;
  338.          Drop        : in Strings.Truncation  := Strings.Error)
  339.          return        Bounded_String
  340.       is
  341.          Result : Bounded_String;
  342.          Llen   : constant Length_Range := Left.Length;
  343.          Rlen   : constant Length_Range := Right.Length;
  344.          Nlen   : constant Natural      := Llen + Rlen;
  345.  
  346.       begin
  347.          if Nlen <= Max_Length then
  348.             Result.Length := Nlen;
  349.             Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
  350.             Result.Data (Llen + 1 .. Nlen) := Right.Data (1 .. Rlen);
  351.  
  352.          else
  353.             Result.Length := Max_Length;
  354.  
  355.             case Drop is
  356.                when Strings.Right =>
  357.                   if Llen >= Max_Length then
  358.                      Result.Data (1 .. Max_Length) :=
  359.                        Left.Data (1 .. Max_Length);
  360.  
  361.                   else
  362.                      Result.Data (1 .. Llen) := Left.Data;
  363.                      Result.Data (Llen + 1 .. Max_Length) :=
  364.                        Right.Data (1 .. Max_Length - Llen);
  365.                   end if;
  366.  
  367.                when Strings.Left =>
  368.                   if Rlen >= Max_Length then
  369.                      Result.Data (1 .. Max_Length) :=
  370.                        Right.Data (Rlen - (Max_Length - 1) .. Rlen);
  371.  
  372.                   else
  373.                      Result.Data (1 .. Max_Length - Rlen) :=
  374.                        Left.Data (Llen - (Max_Length - Rlen + 1) .. Llen);
  375.                      Result.Data (Max_Length - Rlen + 1 .. Max_Length) :=
  376.                        Right.Data (1 .. Rlen);
  377.                   end if;
  378.  
  379.                when Strings.Error =>
  380.                   raise Ada.Strings.Length_Error;
  381.             end case;
  382.          end if;
  383.  
  384.          return Result;
  385.       end Append;
  386.  
  387.       procedure Append
  388.         (Source   : in out Bounded_String;
  389.          New_Item : in Bounded_String;
  390.          Drop     : in Truncation  := Error)
  391.       is
  392.          Llen   : constant Length_Range := Source.Length;
  393.          Rlen   : constant Length_Range := New_Item.Length;
  394.          Nlen   : constant Natural      := Llen + Rlen;
  395.  
  396.       begin
  397.          if Nlen <= Max_Length then
  398.             Source.Length := Nlen;
  399.             Source.Data (Llen + 1 .. Nlen) := New_Item.Data (1 .. Rlen);
  400.  
  401.          else
  402.             Source.Length := Max_Length;
  403.  
  404.             case Drop is
  405.                when Strings.Right =>
  406.                   if Llen < Max_Length then
  407.                      Source.Data (Llen + 1 .. Max_Length) :=
  408.                        New_Item.Data (1 .. Max_Length - Llen);
  409.                   end if;
  410.  
  411.                when Strings.Left =>
  412.                   if Rlen >= Max_Length then
  413.                      Source.Data (1 .. Max_Length) :=
  414.                        New_Item.Data (Rlen - (Max_Length - 1) .. Rlen);
  415.  
  416.                   else
  417.                      Source.Data (1 .. Max_Length - Rlen) :=
  418.                        Source.Data (Llen - (Max_Length - Rlen + 1) .. Llen);
  419.                      Source.Data (Max_Length - Rlen + 1 .. Max_Length) :=
  420.                        New_Item.Data (1 .. Rlen);
  421.                   end if;
  422.  
  423.                when Strings.Error =>
  424.                   raise Ada.Strings.Length_Error;
  425.             end case;
  426.          end if;
  427.  
  428.       end Append;
  429.  
  430.       --  Case of Bounded_String and String
  431.  
  432.       function Append
  433.         (Left  : in Bounded_String;
  434.          Right : in String;
  435.          Drop  : in Strings.Truncation := Strings.Error)
  436.          return  Bounded_String
  437.       is
  438.          Result : Bounded_String;
  439.          Llen   : constant Length_Range := Left.Length;
  440.          Rlen   : constant Length_Range := Right'Length;
  441.          Nlen   : constant Natural      := Llen + Rlen;
  442.  
  443.       begin
  444.          if Nlen <= Max_Length then
  445.             Result.Length := Nlen;
  446.             Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
  447.             Result.Data (Llen + 1 .. Nlen) := Right;
  448.  
  449.          else
  450.             Result.Length := Max_Length;
  451.  
  452.             case Drop is
  453.                when Strings.Right =>
  454.                   if Llen >= Max_Length then
  455.                      Result.Data (1 .. Max_Length) :=
  456.                        Left.Data (1 .. Max_Length);
  457.  
  458.                   else
  459.                      Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
  460.                      Result.Data (Llen + 1 .. Max_Length) :=
  461.                        Right (Right'First .. Right'First - 1 +
  462.                                               Max_Length - Llen);
  463.  
  464.                   end if;
  465.  
  466.                when Strings.Left =>
  467.                   if Rlen >= Max_Length then
  468.                      Result.Data (1 .. Max_Length) :=
  469.                        Right (Right'Last - (Max_Length - 1) .. Right'Last);
  470.  
  471.                   else
  472.                      Result.Data (1 .. Max_Length - Rlen) :=
  473.                        Left.Data (Llen - (Max_Length - Rlen + 1) .. Llen);
  474.                      Result.Data (Max_Length - Rlen + 1 .. Max_Length) :=
  475.                        Right;
  476.                   end if;
  477.  
  478.                when Strings.Error =>
  479.                   raise Ada.Strings.Length_Error;
  480.             end case;
  481.          end if;
  482.  
  483.          return Result;
  484.       end Append;
  485.  
  486.       procedure Append
  487.         (Source   : in out Bounded_String;
  488.          New_Item : in String;
  489.          Drop     : in Truncation  := Error)
  490.       is
  491.          Llen   : constant Length_Range := Source.Length;
  492.          Rlen   : constant Length_Range := New_Item'Length;
  493.          Nlen   : constant Natural      := Llen + Rlen;
  494.  
  495.       begin
  496.          if Nlen <= Max_Length then
  497.             Source.Length := Nlen;
  498.             Source.Data (Llen + 1 .. Nlen) := New_Item;
  499.  
  500.          else
  501.             Source.Length := Max_Length;
  502.  
  503.             case Drop is
  504.                when Strings.Right =>
  505.                   if Llen < Max_Length then
  506.                      Source.Data (Llen + 1 .. Max_Length) :=
  507.                        New_Item (New_Item'First ..
  508.                                        New_Item'First - 1 + Max_Length - Llen);
  509.                   end if;
  510.  
  511.                when Strings.Left =>
  512.                   if Rlen >= Max_Length then
  513.                      Source.Data (1 .. Max_Length) :=
  514.                        New_Item (New_Item'Last - (Max_Length - 1) ..
  515.                                                                 New_Item'Last);
  516.  
  517.                   else
  518.                      Source.Data (1 .. Max_Length - Rlen) :=
  519.                        Source.Data (Llen - (Max_Length - Rlen + 1) .. Llen);
  520.                      Source.Data (Max_Length - Rlen + 1 .. Max_Length) :=
  521.                        New_Item;
  522.                   end if;
  523.  
  524.                when Strings.Error =>
  525.                   raise Ada.Strings.Length_Error;
  526.             end case;
  527.          end if;
  528.  
  529.       end Append;
  530.  
  531.       --  Case of String and Bounded_String
  532.  
  533.       function Append
  534.         (Left  : in String;
  535.          Right : in Bounded_String;
  536.          Drop  : in Strings.Truncation := Strings.Error)
  537.          return  Bounded_String
  538.       is
  539.          Result : Bounded_String;
  540.          Llen   : constant Length_Range := Left'Length;
  541.          Rlen   : constant Length_Range := Right.Length;
  542.          Nlen   : constant Natural      := Llen + Rlen;
  543.  
  544.       begin
  545.          if Nlen <= Max_Length then
  546.             Result.Length := Nlen;
  547.             Result.Data (1 .. Llen) := Left;
  548.             Result.Data (Llen + 1 .. Llen + Rlen) := Right.Data (1 .. Rlen);
  549.  
  550.          else
  551.             Result.Length := Max_Length;
  552.  
  553.             case Drop is
  554.                when Strings.Right =>
  555.                   if Llen >= Max_Length then
  556.                      Result.Data (1 .. Max_Length) :=
  557.                         Left (Left'First .. Left'First + (Max_Length - 1));
  558.  
  559.                   else
  560.                      Result.Data (1 .. Llen) := Left;
  561.                      Result.Data (Llen + 1 .. Max_Length) :=
  562.                        Right.Data (1 .. Max_Length - Llen);
  563.                   end if;
  564.  
  565.                when Strings.Left =>
  566.                   if Rlen >= Max_Length then
  567.                      Result.Data (1 .. Max_Length) :=
  568.                        Right.Data (Rlen - (Max_Length - 1) .. Rlen);
  569.  
  570.                   else
  571.                      Result.Data (1 .. Max_Length - Rlen) :=
  572.                        Left (Left'Last - (Max_Length - Rlen + 1) .. Left'Last);
  573.                      Result.Data (Max_Length - Rlen + 1 .. Max_Length) :=
  574.                        Right.Data (1 .. Rlen);
  575.                   end if;
  576.  
  577.                when Strings.Error =>
  578.                   raise Ada.Strings.Length_Error;
  579.             end case;
  580.          end if;
  581.  
  582.          return Result;
  583.       end Append;
  584.  
  585.       --  Case of Bounded_String and Character
  586.  
  587.       function Append
  588.         (Left  : in Bounded_String;
  589.          Right : in Character;
  590.          Drop  : in Strings.Truncation := Strings.Error)
  591.          return  Bounded_String
  592.       is
  593.          Result : Bounded_String;
  594.          Llen   : constant Length_Range := Left.Length;
  595.  
  596.       begin
  597.          if Llen  < Max_Length then
  598.             Result.Length := Llen + 1;
  599.             Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
  600.             Result.Data (Llen + 1) := Right;
  601.             return Result;
  602.  
  603.          else
  604.             case Drop is
  605.                when Strings.Right =>
  606.                   return Left;
  607.  
  608.                when Strings.Left =>
  609.                   Result.Length := Max_Length;
  610.                   Result.Data (1 .. Max_Length - 1) :=
  611.                     Left.Data (2 .. Max_Length);
  612.                   Result.Data (Max_Length) := Right;
  613.                   return Result;
  614.  
  615.                when Strings.Error =>
  616.                   raise Ada.Strings.Length_Error;
  617.             end case;
  618.          end if;
  619.       end Append;
  620.  
  621.       procedure Append
  622.         (Source   : in out Bounded_String;
  623.          New_Item : in Character;
  624.          Drop     : in Truncation  := Error)
  625.       is
  626.          Llen   : constant Length_Range := Source.Length;
  627.  
  628.       begin
  629.          if Llen  < Max_Length then
  630.             Source.Length := Llen + 1;
  631.             Source.Data (Llen + 1) := New_Item;
  632.  
  633.          else
  634.             Source.Length := Max_Length;
  635.  
  636.             case Drop is
  637.                when Strings.Right =>
  638.                   null;
  639.  
  640.                when Strings.Left =>
  641.                   Source.Data (1 .. Max_Length - 1) :=
  642.                     Source.Data (2 .. Max_Length);
  643.                   Source.Data (Max_Length) := New_Item;
  644.  
  645.                when Strings.Error =>
  646.                   raise Ada.Strings.Length_Error;
  647.             end case;
  648.          end if;
  649.  
  650.       end Append;
  651.  
  652.       --  Case of Character and Bounded_String
  653.  
  654.       function Append
  655.         (Left  : in Character;
  656.          Right : in Bounded_String;
  657.          Drop  : in Strings.Truncation := Strings.Error)
  658.          return  Bounded_String
  659.       is
  660.          Result : Bounded_String;
  661.          Rlen   : constant Length_Range := Right.Length;
  662.  
  663.       begin
  664.          if Rlen < Max_Length then
  665.             Result.Length := Rlen + 1;
  666.             Result.Data (1) := Left;
  667.             Result.Data (2 .. Rlen + 1) := Right.Data (1 .. Rlen);
  668.             return Result;
  669.  
  670.          else
  671.             case Drop is
  672.                when Strings.Right =>
  673.                   Result.Length := Max_Length;
  674.                   Result.Data (1) := Left;
  675.                   Result.Data (2 .. Max_Length) :=
  676.                     Right.Data (1 .. Max_Length - 1);
  677.                   return Result;
  678.  
  679.                when Strings.Left =>
  680.                   return Right;
  681.  
  682.                when Strings.Error =>
  683.                   raise Ada.Strings.Length_Error;
  684.             end case;
  685.          end if;
  686.       end Append;
  687.  
  688.       -----------
  689.       -- Count --
  690.       -----------
  691.  
  692.       function Count
  693.         (Source   : in Bounded_String;
  694.          Pattern  : in String;
  695.          Mapping  : in Maps.Character_Mapping := Maps.Identity)
  696.          return Natural
  697.       is
  698.       begin
  699.          return
  700.            Search.Count (Source.Data (1 .. Source.Length), Pattern, Mapping);
  701.       end Count;
  702.  
  703.       function Count
  704.         (Source   : in Bounded_String;
  705.          Pattern  : in String;
  706.          Mapping  : in Maps.Character_Mapping_Function)
  707.          return Natural
  708.       is
  709.       begin
  710.          return
  711.            Search.Count (Source.Data (1 .. Source.Length), Pattern, Mapping);
  712.       end Count;
  713.  
  714.       function Count
  715.         (Source : in Bounded_String;
  716.          Set    : in Maps.Character_Set)
  717.          return   Natural
  718.       is
  719.       begin
  720.          return Search.Count (Source.Data (1 .. Source.Length), Set);
  721.       end Count;
  722.  
  723.       ------------
  724.       -- Delete --
  725.       ------------
  726.  
  727.       function Delete
  728.         (Source  : in Bounded_String;
  729.          From    : in Positive;
  730.          Through : in Natural)
  731.          return    Bounded_String
  732.       is
  733.          Slen       : constant Natural := Source.Length;
  734.          Num_Delete : constant Integer := Through - From + 1;
  735.          Result     : Bounded_String;
  736.  
  737.       begin
  738.          if Num_Delete <= 0 then
  739.             return Source;
  740.  
  741.          elsif From > Slen + 1 then
  742.             raise Ada.Strings.Index_Error;
  743.  
  744.          elsif Through >= Slen then
  745.             Result.Length := From - 1;
  746.             Result.Data (1 .. From - 1) := Source.Data (1 .. From - 1);
  747.             return Result;
  748.  
  749.          else
  750.             Result.Length := Slen - Num_Delete;
  751.             Result.Data (1 .. From - 1) := Source.Data (1 .. From - 1);
  752.             Result.Data (From .. Result.Length) :=
  753.               Source.Data (Through + 1 .. Slen);
  754.             return Result;
  755.          end if;
  756.       end Delete;
  757.  
  758.       procedure Delete
  759.         (Source  : in out Bounded_String;
  760.          From    : in Positive;
  761.          Through : in Natural)
  762.       is
  763.          Slen       : constant Natural := Source.Length;
  764.          Num_Delete : constant Integer := Through - From + 1;
  765.  
  766.       begin
  767.          if Num_Delete <= 0 then
  768.             return;
  769.  
  770.          elsif From > Slen + 1 then
  771.             raise Ada.Strings.Index_Error;
  772.  
  773.          elsif Through >= Slen then
  774.             Source.Length := From - 1;
  775.  
  776.          else
  777.             Source.Length := Slen - Num_Delete;
  778.             Source.Data (From .. Source.Length) :=
  779.               Source.Data (Through + 1 .. Slen);
  780.          end if;
  781.       end Delete;
  782.  
  783.       -------------
  784.       -- Element --
  785.       -------------
  786.  
  787.       function Element
  788.         (Source : in Bounded_String;
  789.          Index  : in Positive)
  790.          return   Character
  791.       is
  792.       begin
  793.          if Index in 1 .. Source.Length then
  794.             return Source.Data (Index);
  795.          else
  796.             raise Strings.Index_Error;
  797.          end if;
  798.       end Element;
  799.  
  800.       ----------------
  801.       -- Find_Token --
  802.       ----------------
  803.  
  804.       procedure Find_Token
  805.         (Source : in Bounded_String;
  806.          Set    : in Maps.Character_Set;
  807.          Test   : in Strings.Membership;
  808.          First  : out Positive;
  809.          Last   : out Natural)
  810.       is
  811.       begin
  812.          Search.Find_Token
  813.            (Source.Data (1 .. Source.Length), Set, Test, First, Last);
  814.       end Find_Token;
  815.  
  816.  
  817.       ----------
  818.       -- Head --
  819.       ----------
  820.  
  821.       function Head
  822.         (Source : in Bounded_String;
  823.          Count  : in Natural;
  824.          Pad    : in Character := Space;
  825.          Drop   : in Strings.Truncation := Strings.Error)
  826.          return   Bounded_String
  827.       is
  828.          Result : Bounded_String;
  829.          Slen   : constant Natural := Source.Length;
  830.          Npad   : constant Integer := Count - Slen;
  831.  
  832.       begin
  833.          if Npad <= 0 then
  834.             Result.Length := Count;
  835.             Result.Data (1 .. Count) := Source.Data (1 .. Count);
  836.  
  837.          elsif Count <= Max_Length then
  838.             Result.Length := Count;
  839.             Result.Data (1 .. Slen) := Source.Data (1 .. Slen);
  840.             Result.Data (Slen + 1 .. Count) := (others => Pad);
  841.  
  842.          else
  843.             Result.Length := Max_Length;
  844.  
  845.             case Drop is
  846.                when Strings.Right =>
  847.                   Result.Data (1 .. Slen) := Source.Data (1 .. Slen);
  848.                   Result.Data (Slen + 1 .. Max_Length) := (others => Pad);
  849.  
  850.                when Strings.Left =>
  851.                   if Npad >= Max_Length then
  852.                      Result.Data := (others => Pad);
  853.  
  854.                   else
  855.                      Result.Data (1 .. Max_Length - Npad) :=
  856.                        Source.Data (Count - Max_Length + 1 .. Slen);
  857.                      Result.Data (Max_Length - Npad + 1 .. Max_Length) :=
  858.                        (others => Pad);
  859.                   end if;
  860.  
  861.                when Strings.Error =>
  862.                   raise Ada.Strings.Length_Error;
  863.             end case;
  864.          end if;
  865.  
  866.          return Result;
  867.       end Head;
  868.  
  869.       procedure Head
  870.         (Source : in out Bounded_String;
  871.          Count  : in Natural;
  872.          Pad    : in Character  := Space;
  873.          Drop   : in Truncation := Error)
  874.       is
  875.          Slen   : constant Natural := Source.Length;
  876.          Npad   : constant Integer := Count - Slen;
  877.          Temp   : String (1 .. Max_Length);
  878.  
  879.       begin
  880.          if Npad <= 0 then
  881.             Source.Length := Count;
  882.  
  883.          elsif Count <= Max_Length then
  884.             Source.Length := Count;
  885.             Source.Data (Slen + 1 .. Count) := (others => Pad);
  886.  
  887.          else
  888.             Source.Length := Max_Length;
  889.  
  890.             case Drop is
  891.                when Strings.Right =>
  892.                   Source.Data (Slen + 1 .. Max_Length) := (others => Pad);
  893.  
  894.                when Strings.Left =>
  895.                   if Npad > Max_Length then
  896.                      Source.Data := (others => Pad);
  897.  
  898.                   else
  899.                      Temp := Source.Data;
  900.                      Source.Data (1 .. Max_Length - Npad) :=
  901.                        Temp (Count - Max_Length + 1 .. Slen);
  902.  
  903.                      for J in Max_Length - Npad + 1 .. Max_Length loop
  904.                         Source.Data (J) := Pad;
  905.                      end loop;
  906.                   end if;
  907.  
  908.                when Strings.Error =>
  909.                   raise Ada.Strings.Length_Error;
  910.             end case;
  911.          end if;
  912.  
  913.       end Head;
  914.  
  915.       -----------
  916.       -- Index --
  917.       -----------
  918.  
  919.       function Index
  920.         (Source   : in Bounded_String;
  921.          Pattern  : in String;
  922.          Going    : in Strings.Direction := Strings.Forward;
  923.          Mapping  : in Maps.Character_Mapping := Maps.Identity)
  924.          return     Natural
  925.       is
  926.       begin
  927.          return Search.Index
  928.            (Source.Data (1 .. Source.Length), Pattern, Going, Mapping);
  929.       end Index;
  930.  
  931.       function Index
  932.         (Source   : in Bounded_String;
  933.          Pattern  : in String;
  934.          Going    : in Direction := Forward;
  935.          Mapping  : in Maps.Character_Mapping_Function)
  936.          return Natural
  937.       is
  938.       begin
  939.          return Search.Index
  940.            (Source.Data (1 .. Source.Length), Pattern, Going, Mapping);
  941.       end Index;
  942.  
  943.       function Index
  944.         (Source : in Bounded_String;
  945.          Set    : in Maps.Character_Set;
  946.          Test   : in Strings.Membership := Strings.Inside;
  947.          Going  : in Strings.Direction  := Strings.Forward)
  948.          return   Natural
  949.       is
  950.       begin
  951.          return Search.Index
  952.            (Source.Data (1 .. Source.Length), Set, Test, Going);
  953.       end Index;
  954.  
  955.       ---------------------
  956.       -- Index_Non_Blank --
  957.       ---------------------
  958.  
  959.       function Index_Non_Blank
  960.         (Source : in Bounded_String;
  961.          Going  : in Strings.Direction := Strings.Forward)
  962.          return   Natural
  963.       is
  964.       begin
  965.          return
  966.            Search.Index_Non_Blank (Source.Data (1 .. Source.Length), Going);
  967.       end Index_Non_Blank;
  968.  
  969.       ------------
  970.       -- Insert --
  971.       ------------
  972.  
  973.       function Insert
  974.         (Source   : in Bounded_String;
  975.          Before   : in Positive;
  976.          New_Item : in String;
  977.          Drop     : in Strings.Truncation := Strings.Error)
  978.          return     Bounded_String
  979.       is
  980.          Slen    : constant Natural := Source.Length;
  981.          Nlen    : constant Natural := New_Item'Length;
  982.          Tlen    : constant Natural := Slen + Nlen;
  983.          Blen    : constant Natural := Before - 1;
  984.          Alen    : constant Integer := Slen - Blen;
  985.          Droplen : constant Integer := Tlen - Max_Length;
  986.          Result  : Bounded_String;
  987.  
  988.          --  Tlen is the length of the total string before possible truncation.
  989.          --  Blen, Alen are the lengths of the before and after pieces of the
  990.          --  source string.
  991.  
  992.       begin
  993.          if Alen < 0 then
  994.             raise Ada.Strings.Index_Error;
  995.  
  996.          elsif Droplen <= 0 then
  997.             Result.Length := Tlen;
  998.             Result.Data (1 .. Blen) := Source.Data (1 .. Blen);
  999.             Result.Data (Before .. Before + Nlen - 1) := New_Item;
  1000.             Result.Data (Before + Nlen .. Tlen) :=
  1001.               Source.Data (Before .. Slen);
  1002.  
  1003.          else
  1004.             Result.Length := Max_Length;
  1005.  
  1006.             case Drop is
  1007.                when Strings.Right =>
  1008.                   Result.Data (1 .. Blen) := Source.Data (1 .. Blen);
  1009.  
  1010.                   if Droplen > Alen then
  1011.                      Result.Data (Before .. Max_Length) :=
  1012.                        New_Item (New_Item'First
  1013.                                    .. New_Item'First + Max_Length - Before);
  1014.                   else
  1015.                      Result.Data (Before .. Before + Nlen - 1) := New_Item;
  1016.                      Result.Data (Before + Nlen .. Max_Length) :=
  1017.                        Source.Data (Before .. Slen - Droplen);
  1018.                   end if;
  1019.  
  1020.                when Strings.Left =>
  1021.                   Result.Data (Max_Length - (Alen - 1) .. Max_Length) :=
  1022.                     Source.Data (Before .. Slen);
  1023.  
  1024.                   if Droplen >= Blen then
  1025.                      Result.Data (1 .. Max_Length - Alen) :=
  1026.                        New_Item (New_Item'Last - (Max_Length - Alen) + 1
  1027.                                    .. New_Item'Last);
  1028.                   else
  1029.                      Result.Data
  1030.                        (Blen - Droplen + 1 .. Max_Length - Alen) :=
  1031.                          New_Item;
  1032.                      Result.Data (1 .. Blen - Droplen) :=
  1033.                        Source.Data (Droplen + 1 .. Blen);
  1034.                   end if;
  1035.  
  1036.                when Strings.Error =>
  1037.                   raise Ada.Strings.Length_Error;
  1038.             end case;
  1039.          end if;
  1040.  
  1041.          return Result;
  1042.       end Insert;
  1043.  
  1044.       procedure Insert
  1045.         (Source   : in out Bounded_String;
  1046.          Before   : in Positive;
  1047.          New_Item : in String;
  1048.          Drop     : in Strings.Truncation := Strings.Error)
  1049.       is
  1050.       begin
  1051.          --  We do a double copy here because this is one of the situations
  1052.          --  in which we move data to the right, and at least at the moment,
  1053.          --  GNAT is not handling such cases correctly ???
  1054.  
  1055.          Source := Insert (Source, Before, New_Item, Drop);
  1056.       end Insert;
  1057.  
  1058.       ------------
  1059.       -- Length --
  1060.       ------------
  1061.  
  1062.       function Length (Source : in Bounded_String) return Length_Range is
  1063.       begin
  1064.          return Source.Length;
  1065.       end Length;
  1066.  
  1067.       ---------------
  1068.       -- Overwrite --
  1069.       ---------------
  1070.  
  1071.       function Overwrite
  1072.         (Source    : in Bounded_String;
  1073.          Position  : in Positive;
  1074.          New_Item  : in String;
  1075.          Drop      : in Strings.Truncation := Strings.Error)
  1076.          return      Bounded_String
  1077.       is
  1078.          Result  : Bounded_String;
  1079.          Endpos  : constant Natural  := Position + New_Item'Length - 1;
  1080.          Slen    : constant Natural  := Source.Length;
  1081.          Droplen : Natural;
  1082.  
  1083.       begin
  1084.          if Position > Slen + 1 then
  1085.             raise Ada.Strings.Index_Error;
  1086.  
  1087.          elsif New_Item'Length = 0 then
  1088.             return Source;
  1089.  
  1090.          elsif Endpos <= Slen then
  1091.             Result.Length := Source.Length;
  1092.             Result.Data (1 .. Slen) := Source.Data (1 .. Slen);
  1093.             Result.Data (Position .. Endpos) := New_Item;
  1094.             return Result;
  1095.  
  1096.          elsif Endpos <= Max_Length then
  1097.             Result.Length := Endpos;
  1098.             Result.Data (1 .. Position - 1) := Source.Data (1 .. Position - 1);
  1099.             Result.Data (Position .. Endpos) := New_Item;
  1100.             return Result;
  1101.  
  1102.          else
  1103.             Result.Length := Max_Length;
  1104.             Droplen := Endpos - Max_Length;
  1105.  
  1106.             case Drop is
  1107.                when Strings.Right =>
  1108.                   Result.Data (1 .. Position - 1) :=
  1109.                     Source.Data (1 .. Position - 1);
  1110.  
  1111.                   Result.Data (Position .. Max_Length) :=
  1112.                     New_Item (New_Item'First .. New_Item'Last - Droplen);
  1113.                   return Result;
  1114.  
  1115.                when Strings.Left =>
  1116.                   if New_Item'Length >= Max_Length then
  1117.                      Result.Data (1 .. Max_Length) :=
  1118.                         New_Item (New_Item'Last - Max_Length + 1 ..
  1119.                                   New_Item'Last);
  1120.                      return Result;
  1121.  
  1122.                   else
  1123.                      Result.Data (1 .. Max_Length - New_Item'Length) :=
  1124.                        Source.Data (Droplen + 1 .. Position - 1);
  1125.                      Result.Data
  1126.                        (Max_Length - New_Item'Length + 1 .. Max_Length) :=
  1127.                          New_Item;
  1128.                      return Result;
  1129.                   end if;
  1130.  
  1131.                when Strings.Error =>
  1132.                   raise Ada.Strings.Length_Error;
  1133.             end case;
  1134.          end if;
  1135.       end Overwrite;
  1136.  
  1137.       procedure Overwrite
  1138.         (Source    : in out Bounded_String;
  1139.          Position  : in Positive;
  1140.          New_Item  : in String;
  1141.          Drop      : in Strings.Truncation := Strings.Error)
  1142.       is
  1143.          Endpos  : constant Positive := Position + New_Item'Length - 1;
  1144.          Slen    : constant Natural  := Source.Length;
  1145.          Droplen : Natural;
  1146.  
  1147.       begin
  1148.          if Position > Slen + 1 then
  1149.             raise Ada.Strings.Index_Error;
  1150.  
  1151.          elsif Endpos <= Slen then
  1152.             Source.Data (Position .. Endpos) := New_Item;
  1153.  
  1154.          elsif Endpos <= Max_Length then
  1155.             Source.Data (Position .. Endpos) := New_Item;
  1156.             Source.Length := Endpos;
  1157.  
  1158.          else
  1159.             Source.Length := Max_Length;
  1160.             Droplen := Endpos - Max_Length;
  1161.  
  1162.             case Drop is
  1163.                when Strings.Right =>
  1164.                   Source.Data (Position .. Max_Length) :=
  1165.                     New_Item (New_Item'First .. New_Item'Last - Droplen);
  1166.  
  1167.                when Strings.Left =>
  1168.                   if New_Item'Length > Max_Length then
  1169.                      Source.Data (1 .. Max_Length) :=
  1170.                         New_Item (New_Item'Last - Max_Length + 1 ..
  1171.                                   New_Item'Last);
  1172.  
  1173.                   else
  1174.                      Source.Data (1 .. Max_Length - New_Item'Length) :=
  1175.                        Source.Data (Droplen + 1 .. Position - 1);
  1176.  
  1177.                      Source.Data
  1178.                        (Max_Length - New_Item'Length + 1 .. Max_Length) :=
  1179.                          New_Item;
  1180.                   end if;
  1181.  
  1182.                when Strings.Error =>
  1183.                   raise Ada.Strings.Length_Error;
  1184.             end case;
  1185.          end if;
  1186.       end Overwrite;
  1187.  
  1188.       ---------------------
  1189.       -- Replace_Element --
  1190.       ---------------------
  1191.  
  1192.       procedure Replace_Element
  1193.         (Source : in out Bounded_String;
  1194.          Index  : in Positive;
  1195.          By     : in Character)
  1196.       is
  1197.       begin
  1198.          if Index <= Source.Length then
  1199.             Source.Data (Index) := By;
  1200.          else
  1201.             raise Ada.Strings.Index_Error;
  1202.          end if;
  1203.       end Replace_Element;
  1204.  
  1205.       -------------------
  1206.       -- Replace_Slice --
  1207.       -------------------
  1208.  
  1209.       function Replace_Slice
  1210.         (Source   : in Bounded_String;
  1211.          Low      : in Positive;
  1212.          High     : in Natural;
  1213.          By       : in String;
  1214.          Drop     : in Strings.Truncation := Strings.Error)
  1215.          return     Bounded_String
  1216.       is
  1217.          Slen : constant Natural := Source.Length;
  1218.  
  1219.       begin
  1220.          if Low > Slen + 1 then
  1221.             raise Strings.Index_Error;
  1222.  
  1223.          elsif High < Low then
  1224.             return Insert (Source, Low, By, Drop);
  1225.  
  1226.          else
  1227.             declare
  1228.                Blen    : constant Natural := Low - 1;
  1229.                Alen    : constant Natural := Slen - High;
  1230.                Tlen    : constant Natural := Blen + By'Length + Alen;
  1231.                Droplen : constant Integer := Tlen - Max_Length;
  1232.                Result  : Bounded_String;
  1233.  
  1234.                --  Tlen is the total length of the result string before any
  1235.                --  truncation. Blen and Alen are the lengths of the pieces
  1236.                --  of the original string that end up in the result string
  1237.                --  before and after the replaced slice.
  1238.  
  1239.             begin
  1240.                if Droplen <= 0 then
  1241.                   Result.Length := Tlen;
  1242.                   Result.Data (1 .. Blen) := Source.Data (1 .. Blen);
  1243.                   Result.Data (Low .. Low + By'Length - 1) := By;
  1244.                   Result.Data (Low + By'Length .. Tlen) :=
  1245.                     Source.Data (High + 1 .. Slen);
  1246.  
  1247.                else
  1248.                   Result.Length := Max_Length;
  1249.  
  1250.                   case Drop is
  1251.                      when Strings.Right =>
  1252.                         Result.Data (1 .. Blen) := Source.Data (1 .. Blen);
  1253.  
  1254.                         if Droplen > Alen then
  1255.                            Result.Data (Low .. Max_Length) :=
  1256.                              By (By'First .. By'First + Max_Length - Low);
  1257.                         else
  1258.                            Result.Data (Low .. Low + By'Length - 1) := By;
  1259.                            Result.Data (Low + By'Length .. Max_Length) :=
  1260.                              Source.Data (High + 1 .. Slen - Droplen);
  1261.                         end if;
  1262.  
  1263.                      when Strings.Left =>
  1264.                         Result.Data (Max_Length - (Alen - 1) .. Max_Length) :=
  1265.                           Source.Data (High + 1 .. Slen);
  1266.  
  1267.                         if Droplen >= Blen then
  1268.                            Result.Data (1 .. Max_Length - Alen) :=
  1269.                              By (By'Last - (Max_Length - Alen) + 1 .. By'Last);
  1270.                         else
  1271.                            Result.Data
  1272.                              (Blen - Droplen + 1 .. Max_Length - Alen) := By;
  1273.                            Result.Data (1 .. Blen - Droplen) :=
  1274.                              Source.Data (Droplen + 1 .. Blen);
  1275.                         end if;
  1276.  
  1277.                      when Strings.Error =>
  1278.                         raise Ada.Strings.Length_Error;
  1279.                   end case;
  1280.                end if;
  1281.  
  1282.                return Result;
  1283.             end;
  1284.          end if;
  1285.       end Replace_Slice;
  1286.  
  1287.       procedure Replace_Slice
  1288.         (Source   : in out Bounded_String;
  1289.          Low      : in Positive;
  1290.          High     : in Natural;
  1291.          By       : in String;
  1292.          Drop     : in Strings.Truncation := Strings.Error)
  1293.       is
  1294.       begin
  1295.          --  We do a double copy here because this is one of the situations
  1296.          --  in which we move data to the right, and at least at the moment,
  1297.          --  GNAT is not handling such cases correctly ???
  1298.  
  1299.          Source := Replace_Slice (Source, Low, High, By, Drop);
  1300.       end Replace_Slice;
  1301.  
  1302.       ---------------
  1303.       -- Replicate --
  1304.       ---------------
  1305.  
  1306.       function Replicate
  1307.         (Count : in Natural;
  1308.          Item  : in Character;
  1309.          Drop  : in Strings.Truncation := Strings.Error)
  1310.          return  Bounded_String
  1311.       is
  1312.          Result : Bounded_String;
  1313.  
  1314.       begin
  1315.          if Count <= Max_Length then
  1316.             Result.Length := Count;
  1317.  
  1318.          elsif Drop = Strings.Error then
  1319.             raise Ada.Strings.Length_Error;
  1320.  
  1321.          else
  1322.             Result.Length := Max_Length;
  1323.          end if;
  1324.  
  1325.          Result.Data (1 .. Result.Length) := (others => Item);
  1326.          return Result;
  1327.       end Replicate;
  1328.  
  1329.       function Replicate
  1330.         (Count : in Natural;
  1331.          Item  : in String;
  1332.          Drop  : in Strings.Truncation := Strings.Error)
  1333.          return  Bounded_String
  1334.       is
  1335.          Length : constant Integer := Count * Item'Length;
  1336.          Result : Bounded_String;
  1337.          Indx   : Positive;
  1338.  
  1339.       begin
  1340.          if Length <= Max_Length then
  1341.             Result.Length := Length;
  1342.  
  1343.             if Length > 0 then
  1344.                Indx := 1;
  1345.  
  1346.                for J in 1 .. Count loop
  1347.                   Result.Data (Indx .. Indx + Item'Length - 1) := Item;
  1348.                   Indx := Indx + Item'Length;
  1349.                end loop;
  1350.             end if;
  1351.  
  1352.          else
  1353.             Result.Length := Max_Length;
  1354.  
  1355.             case Drop is
  1356.                when Strings.Right =>
  1357.                   Indx := 1;
  1358.  
  1359.                   while Indx + Item'Length <= Max_Length + 1 loop
  1360.                      Result.Data (Indx .. Indx + Item'Length - 1) := Item;
  1361.                      Indx := Indx + Item'Length;
  1362.                   end loop;
  1363.  
  1364.                   Result.Data (Indx .. Max_Length) :=
  1365.                     Item (Item'First .. Item'First + Max_Length - Indx);
  1366.  
  1367.                when Strings.Left =>
  1368.                   Indx := Max_Length;
  1369.  
  1370.                   while Indx - Item'Length >= 1 loop
  1371.                      Result.Data (Indx - (Item'Length - 1) .. Indx) := Item;
  1372.                      Indx := Indx - Item'Length;
  1373.                   end loop;
  1374.  
  1375.                   Result.Data (1 .. Indx) :=
  1376.                     Item (Item'Last - Indx + 1 .. Item'Last);
  1377.  
  1378.                when Strings.Error =>
  1379.                   raise Ada.Strings.Length_Error;
  1380.             end case;
  1381.          end if;
  1382.  
  1383.          return Result;
  1384.       end Replicate;
  1385.  
  1386.       function Replicate
  1387.         (Count : in Natural;
  1388.          Item  : in Bounded_String;
  1389.          Drop  : in Strings.Truncation := Strings.Error)
  1390.          return  Bounded_String
  1391.       is
  1392.       begin
  1393.          return Replicate (Count, Item.Data (1 .. Item.Length), Drop);
  1394.       end Replicate;
  1395.  
  1396.       -----------
  1397.       -- Slice --
  1398.       -----------
  1399.  
  1400.       function Slice
  1401.         (Source : in Bounded_String;
  1402.          Low    : in Positive;
  1403.          High   : in Natural)
  1404.          return   String is
  1405.       begin
  1406.          if Low > Source.Length + 1 then
  1407.             raise Ada.Strings.Index_Error;
  1408.  
  1409.          elsif High > Source.Length then
  1410.  
  1411.             --  Note: RM is not clear on this, but raising Index_Error
  1412.             --  in this situation is what makes consistent sense!
  1413.  
  1414.             raise Ada.Strings.Index_Error;
  1415.  
  1416.          else
  1417.             return Source.Data (Low .. High);
  1418.          end if;
  1419.  
  1420.       end Slice;
  1421.  
  1422.       ----------
  1423.       -- Tail --
  1424.       ----------
  1425.  
  1426.       function Tail
  1427.         (Source : in Bounded_String;
  1428.          Count  : in Natural;
  1429.          Pad    : in Character := Space;
  1430.          Drop   : in Strings.Truncation := Strings.Error)
  1431.          return   Bounded_String
  1432.       is
  1433.          Result : Bounded_String;
  1434.          Slen   : constant Natural := Source.Length;
  1435.          Npad   : constant Integer := Count - Slen;
  1436.  
  1437.       begin
  1438.          if Npad <= 0 then
  1439.             Result.Length := Count;
  1440.             Result.Data (1 .. Count) :=
  1441.               Source.Data (Slen - (Count - 1) .. Slen);
  1442.  
  1443.          elsif Count <= Max_Length then
  1444.             Result.Length := Count;
  1445.             Result.Data (1 .. Npad) := (others => Pad);
  1446.             Result.Data (Npad + 1 .. Count) := Source.Data (1 .. Slen);
  1447.  
  1448.          else
  1449.             Result.Length := Max_Length;
  1450.  
  1451.             case Drop is
  1452.                when Strings.Right =>
  1453.                   if Npad >= Max_Length then
  1454.                      Result.Data := (others => Pad);
  1455.  
  1456.                   else
  1457.                      Result.Data (1 .. Npad) := (others => Pad);
  1458.                      Result.Data (Npad + 1 .. Max_Length) :=
  1459.                        Source.Data (1 .. Max_Length - Npad);
  1460.                   end if;
  1461.  
  1462.                when Strings.Left =>
  1463.                   Result.Data (1 .. Max_Length - Slen) := (others => Pad);
  1464.                   Result.Data (Max_Length - Slen + 1 .. Max_Length) :=
  1465.                     Source.Data (1 .. Slen);
  1466.  
  1467.                when Strings.Error =>
  1468.                   raise Ada.Strings.Length_Error;
  1469.             end case;
  1470.          end if;
  1471.  
  1472.          return Result;
  1473.       end Tail;
  1474.  
  1475.       procedure Tail
  1476.         (Source : in out Bounded_String;
  1477.          Count  : in Natural;
  1478.          Pad    : in Character  := Space;
  1479.          Drop   : in Truncation := Error)
  1480.       is
  1481.          Slen   : constant Natural := Source.Length;
  1482.          Npad   : constant Integer := Count - Slen;
  1483.          Temp   : String (1 .. Max_Length) := Source.Data;
  1484.  
  1485.       begin
  1486.          if Npad <= 0 then
  1487.             Source.Length := Count;
  1488.             Source.Data (1 .. Count) :=
  1489.               Temp (Slen - (Count - 1) .. Slen);
  1490.  
  1491.          elsif Count <= Max_Length then
  1492.             Source.Length := Count;
  1493.             Source.Data (1 .. Npad) := (others => Pad);
  1494.             Source.Data (Npad + 1 .. Count) := Temp (1 .. Slen);
  1495.  
  1496.          else
  1497.             Source.Length := Max_Length;
  1498.  
  1499.             case Drop is
  1500.                when Strings.Right =>
  1501.                   if Npad >= Max_Length then
  1502.                      Source.Data := (others => Pad);
  1503.  
  1504.                   else
  1505.                      Source.Data (1 .. Npad) := (others => Pad);
  1506.                      Source.Data (Npad + 1 .. Max_Length) :=
  1507.                        Temp (1 .. Max_Length - Npad);
  1508.                   end if;
  1509.  
  1510.                when Strings.Left =>
  1511.                   for J in 1 .. Max_Length - Slen loop
  1512.                      Source.Data (J) := Pad;
  1513.                   end loop;
  1514.  
  1515.                   Source.Data (Max_Length - Slen + 1 .. Max_Length) :=
  1516.                     Temp (1 .. Slen);
  1517.  
  1518.                when Strings.Error =>
  1519.                   raise Ada.Strings.Length_Error;
  1520.             end case;
  1521.          end if;
  1522.  
  1523.       end Tail;
  1524.  
  1525.       -----------------------
  1526.       -- To_Bounded_String --
  1527.       -----------------------
  1528.  
  1529.       function To_Bounded_String
  1530.         (Source : in String;
  1531.          Drop   : in Strings.Truncation := Strings.Error)
  1532.          return   Bounded_String
  1533.       is
  1534.          Slen   : constant Natural := Source'Length;
  1535.          Result : Bounded_String;
  1536.  
  1537.       begin
  1538.          if Slen <= Max_Length then
  1539.             Result.Length := Slen;
  1540.             Result.Data (1 .. Slen) := Source;
  1541.  
  1542.          else
  1543.             case Drop is
  1544.                when Strings.Right =>
  1545.                   Result.Length := Max_Length;
  1546.                   Result.Data (1 .. Max_Length) :=
  1547.                     Source (Source'First .. Source'First - 1 + Max_Length);
  1548.  
  1549.                when Strings.Left =>
  1550.                   Result.Length := Max_Length;
  1551.                   Result.Data (1 .. Max_Length) :=
  1552.                     Source (Source'Last - (Max_Length - 1) .. Source'Last);
  1553.  
  1554.                when Strings.Error =>
  1555.                   raise Ada.Strings.Length_Error;
  1556.             end case;
  1557.          end if;
  1558.  
  1559.          return Result;
  1560.       end To_Bounded_String;
  1561.  
  1562.       ---------------
  1563.       -- To_String --
  1564.       ---------------
  1565.  
  1566.       function To_String (Source : in Bounded_String) return String is
  1567.       begin
  1568.          return Source.Data (1 .. Source.Length);
  1569.       end To_String;
  1570.  
  1571.       ---------------
  1572.       -- Translate --
  1573.       ---------------
  1574.  
  1575.       function Translate
  1576.         (Source  : in Bounded_String;
  1577.          Mapping : in Maps.Character_Mapping)
  1578.          return    Bounded_String
  1579.       is
  1580.          Result : Bounded_String;
  1581.  
  1582.       begin
  1583.          Result.Length := Source.Length;
  1584.  
  1585.          for J in 1 .. Source.Length loop
  1586.             Result.Data (J) := Value (Mapping, Source.Data (J));
  1587.          end loop;
  1588.  
  1589.          return Result;
  1590.       end Translate;
  1591.  
  1592.       procedure Translate
  1593.         (Source : in out Bounded_String;
  1594.          Mapping  : in Maps.Character_Mapping)
  1595.       is
  1596.       begin
  1597.          for J in 1 .. Source.Length loop
  1598.             Source.Data (J) := Value (Mapping, Source.Data (J));
  1599.          end loop;
  1600.       end Translate;
  1601.  
  1602.       function Translate
  1603.         (Source  : in Bounded_String;
  1604.          Mapping : in Maps.Character_Mapping_Function)
  1605.          return Bounded_String
  1606.       is
  1607.          Result : Bounded_String;
  1608.  
  1609.       begin
  1610.          Result.Length := Source.Length;
  1611.  
  1612.          for J in 1 .. Source.Length loop
  1613.             Result.Data (J) := Mapping.all (Source.Data (J));
  1614.          end loop;
  1615.  
  1616.          return Result;
  1617.       end Translate;
  1618.  
  1619.       procedure Translate
  1620.         (Source  : in out Bounded_String;
  1621.          Mapping : in Maps.Character_Mapping_Function)
  1622.       is
  1623.       begin
  1624.          for J in 1 .. Source.Length loop
  1625.             Source.Data (J) := Mapping.all (Source.Data (J));
  1626.          end loop;
  1627.       end Translate;
  1628.  
  1629.       ----------
  1630.       -- Trim --
  1631.       ----------
  1632.  
  1633.       function Trim (Source : in Bounded_String; Side : in Trim_End)
  1634.          return Bounded_String
  1635.       is
  1636.          Result : Bounded_String;
  1637.          Last   : Natural := Source.Length;
  1638.          First  : Positive := 1;
  1639.  
  1640.       begin
  1641.          if Side = Left or else Side = Both then
  1642.             while First <= Last and then Source.Data (First) = ' ' loop
  1643.                First := First + 1;
  1644.             end loop;
  1645.          end if;
  1646.  
  1647.          if Side = Right or else Side = Both then
  1648.             while Last >= First and then Source.Data (Last) = ' ' loop
  1649.                Last := Last - 1;
  1650.             end loop;
  1651.          end if;
  1652.  
  1653.          Result.Length := Last - First + 1;
  1654.          Result.Data (1 .. Result.Length) := Source.Data (First .. Last);
  1655.          return Result;
  1656.  
  1657.       end Trim;
  1658.  
  1659.       procedure Trim
  1660.         (Source : in out Bounded_String;
  1661.          Side   : in Trim_End)
  1662.       is
  1663.          Last   : Length_Range := Source.Length;
  1664.          First  : Positive := 1;
  1665.          Temp   : String (1 .. Max_Length);
  1666.  
  1667.       begin
  1668.          Temp (1 .. Last) := Source.Data (1 .. Last);
  1669.  
  1670.          if Side = Left or else Side = Both then
  1671.             while First <= Last and then Temp (First) = ' ' loop
  1672.                First := First + 1;
  1673.             end loop;
  1674.          end if;
  1675.  
  1676.          if Side = Right or else Side = Both then
  1677.             while Last >= First and then Temp (Last) = ' ' loop
  1678.                Last := Last - 1;
  1679.             end loop;
  1680.          end if;
  1681.  
  1682.          Source.Length := Last - First + 1;
  1683.          Source.Data (1 .. Source.Length) := Temp (First .. Last);
  1684.  
  1685.       end Trim;
  1686.  
  1687.       function Trim
  1688.         (Source : in Bounded_String;
  1689.          Left   : in Maps.Character_Set;
  1690.          Right  : in Maps.Character_Set)
  1691.          return   Bounded_String
  1692.       is
  1693.          Result : Bounded_String;
  1694.  
  1695.       begin
  1696.          for First in 1 .. Source.Length loop
  1697.             if not Is_In (Source.Data (First), Left) then
  1698.                for Last in reverse First .. Source.Length loop
  1699.                   if not Is_In (Source.Data (Last), Right) then
  1700.                      Result.Length := Last - First + 1;
  1701.                      Result.Data (1 .. Result.Length) :=
  1702.                         Source.Data (First .. Last);
  1703.                      return Result;
  1704.                   end if;
  1705.                end loop;
  1706.             end if;
  1707.          end loop;
  1708.  
  1709.          Result.Length := 0;
  1710.          return Result;
  1711.       end Trim;
  1712.  
  1713.       procedure Trim
  1714.         (Source : in out Bounded_String;
  1715.          Left   : in Maps.Character_Set;
  1716.          Right  : in Maps.Character_Set)
  1717.       is
  1718.       begin
  1719.          for First in 1 .. Source.Length loop
  1720.             if not Is_In (Source.Data (First), Left) then
  1721.                for Last in reverse First .. Source.Length loop
  1722.                   if not Is_In (Source.Data (Last), Right) then
  1723.                      if First = 1 then
  1724.                         Source.Length := Last;
  1725.                         return;
  1726.                      else
  1727.                         Source.Length := Last - First + 1;
  1728.                         Source.Data (1 .. Source.Length) :=
  1729.                           Source.Data (First .. Last);
  1730.                         return;
  1731.                      end if;
  1732.                   end if;
  1733.                end loop;
  1734.  
  1735.                Source.Length := 0;
  1736.                return;
  1737.             end if;
  1738.          end loop;
  1739.  
  1740.          Source.Length := 0;
  1741.       end Trim;
  1742.  
  1743.    end Generic_Bounded_Length;
  1744.  
  1745. end Ada.Strings.Bounded;
  1746.